#include "IndiceSecuencial.h"
#include "../estrategiaAlmacenamiento/Iterador.h"
#include "../recursoDeAlmacenamiento/RecursoDeAlmacenamiento.h"
#include "../claves/TipoClave.h"
#include "TipoClaveElemento.h"
#include "../recursoDeAlmacenamiento/FabricaRecursosAlmacenamiento.h"
#include "Elemento.h"
#include "../estrategiaAlmacenamiento/EstrategiaAlmacenamiento.h"

#include <string>
using namespace std;

IndiceSecuencial::IndiceSecuencial(TipoClave* extractor, string path) :
			Indice(extractor) {

	this->archivo =
			FabricaRecursosAlmacenamiento::getFabrica()->crearRecursoArchivoBloques(path,20);
}

IndiceSecuencial::~IndiceSecuencial() {
	delete archivo;
}

bool IndiceSecuencial::indexar(RecursoDeAlmacenamiento* recurso) {

	if (recurso != NULL && archivo != NULL) {

		Iterador* it = recurso->getIterador();
		it->reiniciarIterador();

		while (it->tieneSiguiente()) {
			offset o = it->getOffset();
			Bytes b = it->getSiguiente();
			this->agregar(extractor->crearClave(extractor->extraerClave(b)), o);
		}

		delete it;
		return true;
	}
	return false;
}

bool IndiceSecuencial::getNumComponente(Key clave, offset& numComponente) {

	Iterador* it = this->archivo->getIterador();

	while (it->tieneSiguiente()) {
		Bytes elementoSerializado = it->getSiguiente();
		Elemento elemento;
		elemento.hidratarse(elementoSerializado, this->extractor);
		if (clave == elemento.getClave()) {
			numComponente = elemento.getDato();
			delete it;
			return true;
		}
	}
	delete it;
	return false;
}

bool IndiceSecuencial::agregar(Key clave, offset numComponente) {
	Elemento elemento(clave,numComponente);
	Bytes serializacion = elemento.serializarse();
	serializacion.getTamanio();
	this->archivo->guardar(elemento.serializarse());
	return true;
}

bool IndiceSecuencial::quitar(Key clave, offset& numComponente) {

	Iterador* it = this->archivo->getIterador();

	while (it->tieneSiguiente()) {
		Bytes elementoSerializado = it->getSiguiente();
		Elemento elemento;
		elemento.hidratarse(elementoSerializado, this->extractor);
		if (clave == elemento.getClave()) {
			numComponente = elemento.getDato();
			delete it;
			return true;
		}
	}
	delete it;
	return false;
}

bool IndiceSecuencial::existeClave(Key clave){
	Iterador* it = this->archivo->getIterador();

	while (it->tieneSiguiente()) {
		Bytes elementoSerializado = it->getSiguiente();
		Elemento elemento;
		elemento.hidratarse(elementoSerializado, this->extractor);
		if (clave == elemento.getClave()) {
			delete it;
			return true;
		}
	}
	return false;

}

